如何将嵌入在 bash/shell 脚本中的长 sed 命令跨多行包装?
How do I wrap a long sed command embedded within a bash/shell script across multiple lines?
在我的 shell 脚本中,我将 for 循环的输出通过管道传输到带有长“s|||”的嵌入式 sed 命令中替换语句,如下:
#/usr/bin/bash
output=/cygdrive/c/output.csv
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e "s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)|$i,,--,,,,|"
done >> $output
sed 命令太长,所以我的问题是如何在打破它的情况下将 sed 行换行到多行?
例如:
#/usr/bin/bash
output=/cygdrive/c/output.csv
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e
"s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)
|$i,,--,,,,|"
done >> $output
你能把那个特定的字符串放在一个变量中吗:
SED_PATTERN="s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]"
SED_PATTERN+="\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)"
SED_PATTERN+="|$i,,--,,,,|"
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e "$SED_PATTERN"
done >> $output
我认为这是最干净的方式。
我无法在上面的评论中很好地格式化代码,所以这是我所做的工作:
#/usr/bin/bash
output=/cygdrive/c/output.csv
PATTERN="^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)"
REPLACE=",--,,,,"
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.bfc" -printf "%p %k\n" |
sed -e "s|$PATTERN|$i,$REPLACE|"
done >> $output
感谢 Jose B. for your 以上。
a} 您可以使用 "" 符号(不带引号)使一行换行到末尾。
b} 如果你给我一个更详细的例子来说明你实际在做什么,我可以 90% 向你保证,这个问题有比正则表达式更简单的解决方案。
如果我一次只想匹配一两个东西,我只会使用正则表达式。如果我需要更复杂的东西,那么我将首先在 ed 中使用一个简单的正则表达式来尽可能接近文件,然后使用相对行编号完成剩下的工作,提取相关行ed,根据需要用其他程序更改它们,然后要么只使用新创建的文件,要么将更改与原始文件合并。
您可以使用连续字符保留原始脚本,而无需求助于其他 shell 变量:
sed -e \
"s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\
\([0-9]\+\)\.bfc\ \([0-9]\+\)\
|$i,,--,,,,|"
在我的 shell 脚本中,我将 for 循环的输出通过管道传输到带有长“s|||”的嵌入式 sed 命令中替换语句,如下:
#/usr/bin/bash
output=/cygdrive/c/output.csv
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e "s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)|$i,,--,,,,|"
done >> $output
sed 命令太长,所以我的问题是如何在打破它的情况下将 sed 行换行到多行?
例如:
#/usr/bin/bash
output=/cygdrive/c/output.csv
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e
"s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)
|$i,,--,,,,|"
done >> $output
你能把那个特定的字符串放在一个变量中吗:
SED_PATTERN="s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]"
SED_PATTERN+="\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)"
SED_PATTERN+="|$i,,--,,,,|"
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e "$SED_PATTERN"
done >> $output
我认为这是最干净的方式。
我无法在上面的评论中很好地格式化代码,所以这是我所做的工作:
#/usr/bin/bash
output=/cygdrive/c/output.csv
PATTERN="^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)"
REPLACE=",--,,,,"
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.bfc" -printf "%p %k\n" |
sed -e "s|$PATTERN|$i,$REPLACE|"
done >> $output
感谢 Jose B. for your
a} 您可以使用 "" 符号(不带引号)使一行换行到末尾。
b} 如果你给我一个更详细的例子来说明你实际在做什么,我可以 90% 向你保证,这个问题有比正则表达式更简单的解决方案。
如果我一次只想匹配一两个东西,我只会使用正则表达式。如果我需要更复杂的东西,那么我将首先在 ed 中使用一个简单的正则表达式来尽可能接近文件,然后使用相对行编号完成剩下的工作,提取相关行ed,根据需要用其他程序更改它们,然后要么只使用新创建的文件,要么将更改与原始文件合并。
您可以使用连续字符保留原始脚本,而无需求助于其他 shell 变量:
sed -e \
"s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\
\([0-9]\+\)\.bfc\ \([0-9]\+\)\
|$i,,--,,,,|"