允许用户在数组中选择文件后完成parallel/xargs命令(函数);在printf脚本中正确引用nuls



这是这个问题的后续问题

在这个问题中,我可以将选定的文件放入一个数组中,并将它们传递给一个命令/函数(已经导出(。这个问题的不同之处在于,我希望用户在选择文件后完成命令。

主要目的:我收到了一份文件名列表(FZF(。我手动选择其中一些。然后FZF将这个子集放入一个数组中。然后我想编写一个未完成的命令,期望用户完成该命令并按Enter

文件名中可以有空格;因此选择空分隔。

我正在使用FZF来选择文件。我认为,它生成了一个包含nul结尾文件名的数组。但FZF产生的第一个项目是按键的名称。这就是脚本以不同方式处理FZF输出的第一项的原因。

目前我有

#!/bin/bash
readarray -d '' out < <(fd .|fzf  --print0 -e -m  --expect=ctrl-e,ctrl-l)
if [ ${#out[@]} -eq 0 ]; then return 0
fi
declare -p out
key="$out"
y=${out[@]:1}
if [ ${#y[@]} -eq 0 ]; then return 0
fi
case "$key" in
ctrl-e ) echo do something ;;
ctrl-l ) echo do something else ;;
* )
printf -v array_str '%q ' "${y[@]}"
cmd="printf '%s' ${array_str} | parallel -0 wc"
read -e -i "$cmd" cmd_edited; eval "$cmd_edited" ;; #not working
esac

我已经接近了:命令看起来应该如此,但NUL值没有表现出来。最后一行不起作用。它的目的是在带有空分隔符的行上打印文件数组,并允许用户在点击Enter之前指定一个函数(已导出(。parallel命令将该函数应用于数组中的每个文件。

$ls
file 1
file 2
...
...
file 100

目前,如果我选择file 3file 2,我的脚本输出如下:

printf "%s" file 3 file 2 | parallel -0

例如,我可以将wc附加到

但在我键入wc并按Enter后,我得到以下结果:

printf "%s" file 3 file 2 | parallel -0 wc
wc: file030file020: No such file or directory

编辑:我现在已经包含了declare -p out行,以明确FZF正在生产什么。现在出现的结果,使用查尔斯的修改如下:

declare -a out=([0]="" [1]="file 3" [2]="file 2" [3]="file 1")
printf '%s' file 3 file 2 file 1  | parallel -0 wc
wc: file030file020file010: No such file or directory

所以nuls显然出了问题。

如何修复代码?

我还不清楚你想做什么。注释你的代码,确保每个变量名都有一个名称,说明它的用途。

是否希望用户能够输入命令并在阵列中的文件上运行该命令?

# Set y
y=("file  1" "file "two"")
# What command does the user want to run?
# The command is a GNU Parallel command template
# So {} will be replaced with the argument
IFS= read -r command_to_run
# Run $command_to_run for every @y.
# -0 is needed if an element in @y contains n
parallel -0 "$command_to_run" ::: "${y[@]}"

或者:

# Set default command template
cmd='printf "%s" "${y[@]}" | parallel -0 wc'
# Let the user edit the template
IFS= read -r -e -i "$cmd"
# Run the input
eval "$REPLY"

忽略fzfparallel是否符合您的要求,以下内容肯定不会:

cmd="printf "%s" ${y[@]} | parallel -0 wc"

为什么?因为${y[@]}不插入使y数组的内容表示为有效的shell语法所必需的引用和转义(通过eval反馈时引用数据的原始内容(。


如果要将数据插入将被解析为代码的字符串中,则需要首先对其进行转义。shell可以使用printf %q:为您做到这一点

printf -v array_str '%q ' "${y[@]}"
cmd="printf '%s' ${array_str} | parallel -0 wc"
IFS= read -r -e -i "$cmd" cmd_edited; eval "$cmd_edited"

相关内容

  • 没有找到相关文章

最新更新