【问题标题】:Exec and sed commands执行和 sed 命令
【发布时间】:2019-02-06 22:35:49
【问题描述】:

问题是如何将以下命令组合成一行并使用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

字符串A

第一行

第2行

字符串B

./beta/file02.txt

字符串A

第一行

第2行

字符串B

谢谢。 T.

【问题讨论】:

  • 如果是我,我会编写一个脚本,将文件名列表(可能为空)作为参数,然后对每个参数进行处理:例如for file in "$@"; do echo "$file"; sed -n '/StringA/,/StringB/p' "$file"; done。把它放在一个文件中——findit.sh。然后find . -type f -name '*.txt' -exec sh findit.sh {} + 完成剩下的工作。如果您需要将StringAStringB 变成findit.sh 的参数,就这样吧;要求它们作为前两个参数并相应地调整脚本。唯一的问题是名称 findit.sh 并在您动态创建时将其删除。

标签: shell sed exec


【解决方案1】:

如果文件不是空的,那么你只需要:

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

如果它们可以为空,那么处理它的最简单方法是使用 GNU awk 作为 BEGINFILE:

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

【讨论】:

  • 非常简单的解决方案。我通过 SED 测试了其他变体,但它比您的 AWK 解决方案慢大约两倍,语法也更难一些。谢谢你。例如 SED 解决方案:find . -name '*.txt' -exec sh -c 'echo "$0" ; sed -n "/StringA/,/StringB/p" "$0"' {} \;
  • 不客气。 sed 非常适合单个行上的 s/old/new,其中 old 是正则表达式,new 是启用反向引用的字符串。对于其他任何事情,只需使用 awk 来实现简单性、清晰性、效率、可移植性、稳健性等。
【解决方案2】:

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 作为文件名。

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    使用 GNU sedrealpath

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

    或者,如果可以接受相对路径:

    sed -sn '1F;/stringA/,/stringB/p' ./*.txt
    

    如果代码需要递归到子目录:

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

    【讨论】:

      猜你喜欢
      • 2011-08-01
      • 2019-07-22
      • 1970-01-01
      • 2013-06-05
      • 2017-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多