变量中有以下字符串:
-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命令来做这件事吗?
所以让我把我的问题说得更清楚一点。我使用sftp文件执行-b命令,在其中执行ls -l *.zip命令。结果会进入一个文件中。首先,我使用一个sed命令来清除前2行,因为对我来说这些都是无关的信息。我现在只有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发布于 2019-12-09 15:44:07
关于订正设想方案的说明
这个问题已被修改为包括一个shell片段:
ListOfFiles=$(sed '1,2d‘$LstFile) #删除$ListOfFiles do $line=$中行的前2行
将结果保存到变量中,就像在第一行中一样,这是处理它的错误方法。您可以使用我原来答案中的代码的简单调整(下面)来简单地实现您的需求--非常简单地使用awk,但是如果您挂在使用sed上,就可以使用sed对原始代码进行简单的调整。
awk 变体
awk 'NR <= 2 { next } { print $6, $7, $8, $9 }' $LstFileNR <= 2 { next }部分跳过前两行;其余行不变,只是数据源是您下载的列表文件。
sed 变体
sed -nE -e '1,2d' -e 's/^([^ ]+[ ]+){5}([^ ]+([ ]+[^ ]+){3})$/\2/p' $LstFile实际上,1,2d命令不太可能是必要的,但使用它更安全,以防前两行中的一行有9个字段。(是的,我可以避免两次使用-e选项-不,我更喜欢在单独的选项中使用单独的命令;这样可以更容易地阅读IMO。)
原来问题的答案
如果将此视为字符串操作中的练习(不考虑尝试parse the output from ls reliably的正当警告),则不需要sed。事实上,sed几乎肯定是该工作的错误工具-- awk将是一个更好的选择--但是可以单独使用shell。例如,假设数据位于字符串$variable中,可以使用:
set -- $variable
echo $6 $7 $8 $9
echo $15 $16 $17 $18这给了你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个字段”。
假设-E选项到sed启用了扩展正则表达式,那么您可以使用:
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)保留赋值中的间距(特别是换行符)(请参见Capturing multiple line output into a Bash variable)。因此,sed显示的应用于您的可能性不大,但这并不确定,因为在发布此答案之前,您没有回答所要求的澄清。
发布于 2019-12-09 15:47:35
正如其他人说的那样,您不应该真的解析ls输出。否则,一种使用awk打印您感兴趣的列的虚拟方法:
awk '{print $6, $7, $8, $9 "\n" $15, $16, $17, $18}' <<< $your_variablehttps://stackoverflow.com/questions/59251015
复制相似问题