Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell Exec和sed命令_Shell_Sed_Exec - Fatal编程技术网

Shell Exec和sed命令

Shell Exec和sed命令,shell,sed,exec,Shell,Sed,Exec,问题是如何在一行中组合以下命令并使用exec find . -name '*.txt' -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \; 结果:所有.txt文件的路径和名称 find . -name '*.txt' -exec sed -n '/stringA/,/stringB/p' {} \; 结果是:所有.txt文件的开始和结束参数之间的行 请求的结果:在开始和结束参数之间给我行。第一行必须包含.txt文件的路径和名称 find

问题是如何在一行中组合以下命令并使用exec

find . -name '*.txt' -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;
结果:所有.txt文件的路径和名称

find . -name '*.txt' -exec sed -n '/stringA/,/stringB/p' {} \;
结果是:所有.txt文件的开始和结束参数之间的行

请求的结果:在开始和结束参数之间给我行。第一行必须包含.txt文件的路径和名称

find . -name '*.txt' -exec ???? {} \;
./alpha/file01.txt

斯特林加

第1行

第2行

斯特林布

./beta/file02.txt

斯特林加

第1行

第2行

斯特林布

谢谢。
T.

find
的输出通过管道传输到其他命令可能比使用
-exec
更容易。请尝试以下操作:

find . -type f -name '*.txt' -print0 | while read -r -d "" f; do echo "$f"; sed -n "/stringA/,/stringB/p" "$f"; done
这将产生:

./alpha/file01.txt
stringA
line1
line2
stringB
./beta/file02.txt
stringA
line1
line2
stringB
  • -find
    中的print0选项合并由空字符分隔的文件名
  • read
    中的
    -d”“
    选项将输入拆分为一个空字符,以正确复制文件名列表
  • 然后我们可以在
    while
    循环中将
    $f
    作为文件名引用

希望这有帮助。

find
的输出通过管道传输到其他命令可能比使用
-exec
更容易。请尝试以下操作:

find . -type f -name '*.txt' -print0 | while read -r -d "" f; do echo "$f"; sed -n "/stringA/,/stringB/p" "$f"; done
这将产生:

./alpha/file01.txt
stringA
line1
line2
stringB
./beta/file02.txt
stringA
line1
line2
stringB
  • -find
    中的print0选项合并由空字符分隔的文件名
  • read
    中的
    -d”“
    选项将输入拆分为一个空字符,以正确复制文件名列表
  • 然后我们可以在
    while
    循环中将
    $f
    作为文件名引用
希望这有帮助。

使用GNU
sed
realpath

sed -sn '1F;/stringA/,/stringB/p' $(realpath *.txt)
或者,如果可以接受相对路径:

sed -sn '1F;/stringA/,/stringB/p' ./*.txt
如果代码需要递归到子目录中:

sed -sn '1F;/stringA/,/stringB/p'  $(find . -name '*.txt')
使用GNU
sed
realpath

sed -sn '1F;/stringA/,/stringB/p' $(realpath *.txt)
或者,如果可以接受相对路径:

sed -sn '1F;/stringA/,/stringB/p' ./*.txt
如果代码需要递归到子目录中:

sed -sn '1F;/stringA/,/stringB/p'  $(find . -name '*.txt')

如果文件不为空,则只需:

find . -name '*.txt' -exec awk 'FNR==1{print FILENAME} /StringA/,/StringB/' {} +
如果它们可以为空,那么最简单的处理方法是使用GNU awk for BEGINFILE:

find . -name '*.txt' -exec awk 'BEGINFILE{print FILENAME} /StringA/,/StringB/' {} +

如果文件不为空,则只需:

find . -name '*.txt' -exec awk 'FNR==1{print FILENAME} /StringA/,/StringB/' {} +
如果它们可以为空,那么最简单的处理方法是使用GNU awk for BEGINFILE:

find . -name '*.txt' -exec awk 'BEGINFILE{print FILENAME} /StringA/,/StringB/' {} +

如果是我,我会编写一个脚本,将文件名列表(可能为空)作为参数,然后对每个参数进行处理:
用于“$@”中的文件;不回显“$file”;sed-n'/StringA/,/StringB/p'$file”;例如,完成。将其放入一个文件-
findit.sh
。然后
find-键入f-name'*.txt'-exec sh findit.sh{}+
执行其余操作。如果需要将
StringA
StringB
转换为
findit.sh
的参数,就这样吧;要求将它们作为前两个参数,并相应地调整脚本。唯一的问题是名称
findit.sh
,如果您动态创建它,就会将其删除。如果是我,我会编写一个脚本,将文件名列表(可能为空)作为参数,然后对每个参数进行处理:
for file in“$@”;不回显“$file”;sed-n'/StringA/,/StringB/p'$file”;例如,完成。将其放入一个文件-
findit.sh
。然后
find-键入f-name'*.txt'-exec sh findit.sh{}+
执行其余操作。如果需要将
StringA
StringB
转换为
findit.sh
的参数,就这样吧;要求将它们作为前两个参数,并相应地调整脚本。唯一的问题是名称
findit.sh
,如果您动态创建它,则将其删除。这是一个非常简单的解决方案。我用SED测试了另一个变体,但它大约比您的AWK解决方案慢两倍,语法也稍微困难一些。非常感谢。例如SED解决方案:
find-名称'*.txt'-exec sh-c'echo“$0”;sed-n“/StringA/,/StringB/p”“$0”“{}\不客气。sed非常适合在单独的行上使用s/old/new,其中old是一个regexp,new是一个支持反向引用的字符串。对于其他任何事情,只需使用awk来实现简单性、清晰性、效率、可移植性、健壮性等。这是一个非常简单的解决方案。我用SED测试了另一个变体,但它大约比您的AWK解决方案慢两倍,语法也稍微困难一些。非常感谢。例如SED解决方案:
find-名称'*.txt'-exec sh-c'echo“$0”;sed-n“/StringA/,/StringB/p”“$0”“{}\不客气。sed非常适合在单独的行上使用s/old/new,其中old是一个regexp,new是一个支持反向引用的字符串。对于其他任何东西,只需使用awk以实现简单性、清晰性、效率、可移植性、健壮性等。