在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 }'
这两种方法都会在空格处自动拆分字符串,并允许您引用拆分的元素