在bashshell中使用for循环和sed拆分字符串
变量中有以下字符串:在bashshell中使用for循环和sed拆分字符串,bash,shell,Bash,Shell,变量中有以下字符串: -rw-r--r--0 1068 1001 4870 Dec 6 11:58 1.zip-rw-r--r--0 1068 1001 20246 Dec 6 11:59 10.zip 我尝试使用for循环遍历此字符串,并得到以下结果: Dec 6 11:58 1.zip Dec 6 11:59 10.zip 有人有正确的sed命令来执行此操作吗 让我把我的问题说清楚一点。我使用-b文件执行sftp命令,并在其中执行ls-l*.zip。此操作的结果将进入一个文件。首先,我使
-rw-r--r--0 1068 1001 4870 Dec 6 11:58 1.zip-rw-r--r--0 1068 1001 20246 Dec 6 11:59 10.zip
我尝试使用for循环遍历此字符串,并得到以下结果:
Dec 6 11:58 1.zip
Dec 6 11:59 10.zip
有人有正确的sed命令来执行此操作吗
让我把我的问题说清楚一点。我使用
-b
文件执行sftp
命令,并在其中执行ls-l*.zip
。此操作的结果将进入一个文件。首先,我使用sed
命令清除前两行,因为它们对我来说是不相关的信息。我现在只有ls
结果,但它们在一行上。在我的示例中,只有2个zip文件,但可以有更多
ListOfFiles=$(sed '1,2d' $LstFile) #delete first 2 lines
for line in $ListOfFiles
do
$line=$(echo "${line}" | sed (here i want the command to ony print zip file and date)
done
关于修订设想的说明
该问题已修改为包含一个外壳片段:
将结果保存到变量中(如第一行所示)是处理它的错误方法。您可以在我的原始答案(以下)中使用简单的代码改编来实现您的要求-非常简单地使用awk
,但是如果您挂断了使用sed
,可以使用sed
对原始代码进行简单改编
awk
variant
awk 'NR <= 2 { next } { print $6, $7, $8, $9 }' $LstFile
sed -nE -e '1,2d' -e 's/^([^ ]+[ ]+){5}([^ ]+([ ]+[^ ]+){3})$/\2/p' $LstFile
实际上,不太可能需要使用1,2d
命令,但使用它更安全,只是为了防止前两行中有一行有9个字段。(是的,我可以避免两次使用-e
选项-不,我更喜欢在单独的选项中使用单独的命令;这样更易于阅读。)
原问题的答案
如果您将此视为字符串操作中的练习(忽略有关尝试的合法警告),则不需要使用sed
。事实上,sed
对于这项工作来说几乎肯定是一个错误的工具-awk
将是一个更好的选择-但是可以单独使用shell。例如,假设数据位于字符串$variable
中,则可以使用:
set -- $variable
echo $6 $7 $8 $9
echo $15 $16 $17 $18
variable="-rw-r--r-- 0 1068 1001 4870 Dec 6 11:58 1.zip
-rw-r--r-- 0 1068 1001 20246 Dec 6 11:59 10.zip"
echo "$variable" |
sed -nE 's/^([^[:space:]]+[[:space:]]+){5}([^[:space:]]+([[:space:]]+[^[:space:]]+){3})$/\2/p'
这将为您提供18个位置参数,并打印您感兴趣的8个参数。使用awk
,您可以使用:
echo $variable | awk '{ print $6, $7, $8, $9; print $15, $16, $17, $18 }'
这两种方法都会在空格处自动拆分字符串,并允许您使用数字引用拆分的元素。使用sed
,您不会得到自动拆分,这使得工作极其繁琐
假设变量实际上包含两行,那么:
echo "$variable"
报告:
-rw-r--r-- 0 1068 1001 4870 Dec 6 11:58 1.zip
-rw-r--r-- 0 1068 1001 20246 Dec 6 11:59 10.zip
上面的代码假定$variable
的内容是一行(尽管如果变量包含两行,则其工作原理不变),但下面的代码假定它包含两行。事实上,如果$variable
包含许多行,那么下面的代码就可以工作,而set
和awk
版本与“输入中的18个字段”绑定
假设sed
的-E
选项启用扩展正则表达式,则可以使用:
set -- $variable
echo $6 $7 $8 $9
echo $15 $16 $17 $18
variable="-rw-r--r-- 0 1068 1001 4870 Dec 6 11:58 1.zip
-rw-r--r-- 0 1068 1001 20246 Dec 6 11:59 10.zip"
echo "$variable" |
sed -nE 's/^([^[:space:]]+[[:space:]]+){5}([^[:space:]]+([[:space:]]+[^[:space:]]+){3})$/\2/p'
这将查找一个非空白字符序列,后跟一个空白字符序列,重复5次,后跟一个非空白字符序列和3组空白字符序列,后跟一个非空白字符序列。分组括号-因此将字段1-5挑选到\1
(忽略),将字段6-9挑选到\2
(保留),然后打印结果。如果您决定不使用选项卡等,则可以将sed
命令简化为:
echo "$variable" | sed -nE 's/^([^ ]+[ ]+){5}([^ ]+([ ]+[^ ]+){3})$/\2/p'
这两种方法都会产生输出:
Dec 6 11:58 1.zip
Dec 6 11:59 10.zip
处理输入的单行变量是非常痛苦的-足够了,所以我不打算展示它
请注意,使用$variable
中的两行值,awk
版本可能会变成:
echo "$variable" | awk '{ print $6, $7, $8, $9 }'
这也将处理任意数量的行
请注意,理解echo$variable
和echo“$variable”
之间的区别是多么重要。第一种方法将所有空白序列视为等同于单个空白,但另一种方法保留内部间距。以及捕获输出,例如:
variable=$(ls -l 1*.zip)
保留指定中的间距(尤其是换行符)(请参见)。因此,所示的sed
对您有效的可能性不大,但这并不确定,因为您在发布此答案之前没有回答所要求的澄清。关于修订方案的注释
该问题已修改为包含一个外壳片段:
将结果保存到变量中(如第一行所示)是处理它的错误方法。您可以在我的原始答案(以下)中使用简单的代码改编来实现您的要求-非常简单地使用awk
,但是如果您挂断了使用sed
,可以使用sed
对原始代码进行简单改编
awk
variant
awk 'NR <= 2 { next } { print $6, $7, $8, $9 }' $LstFile
sed -nE -e '1,2d' -e 's/^([^ ]+[ ]+){5}([^ ]+([ ]+[^ ]+){3})$/\2/p' $LstFile
实际上,不太可能需要使用1,2d
命令,但使用它更安全,只是为了防止前两行中有一行有9个字段。(是的,我可以避免两次使用-e
选项-不,我更喜欢在单独的选项中使用单独的命令;这样更易于阅读。)
原问题的答案
如果您将此视为字符串操作中的练习(忽略有关尝试的合法警告),则不需要使用sed
。事实上,sed
对于这项工作来说几乎肯定是一个错误的工具-awk
将是一个更好的选择-但是可以单独使用shell。例如,假设数据位于字符串$variable
中,则可以使用:
set -- $variable
echo $6 $7 $8 $9
echo $15 $16 $17 $18
variable="-rw-r--r-- 0 1068 1001 4870 Dec 6 11:58 1.zip
-rw-r--r-- 0 1068 1001 20246 Dec 6 11:59 10.zip"
echo "$variable" |
sed -nE 's/^([^[:space:]]+[[:space:]]+){5}([^[:space:]]+([[:space:]]+[^[:space:]]+){3})$/\2/p'
这将为您提供18个位置参数,并打印您感兴趣的8个参数。使用awk
,您可以使用:
echo $variable | awk '{ print $6, $7, $8, $9; print $15, $16, $17, $18 }'
这两种方法都会在空格处自动拆分字符串,并允许您引用拆分的元素