gpt4 book ai didi

linux - Awk:如何用新行构建一个字符串变量?

转载 作者:可可西里 更新时间:2023-11-01 11:48:32 24 4
gpt4 key购买 nike

我正在尝试执行以下操作:

ls -l 在文件夹上的结果:

-rw-rw-r--   1 root  root  100  May 23 09:45 filename1
-rw-rw-r-- 1 root root 200 May 23 09:45 filename2
-rw-rw-r-- 1 root root 500 May 23 09:46 filename3

现在我想通过 awk 传递它来执行以下操作:

800 bytes, files:
filename1
filename2
filename3

到目前为止,我可以使用 awk 来计算字节数:

output=`ls -l /some/folder/ | awk 'START {total = 0}; {total += $5} END{print total}'`

这个简单的给出:800

现在我想开始构建输出字符串,所以我试图获取文件名列表(我认为是 $9 列),我正在尝试这样做:

output=`ls -l /some/folder/ | awk 'START {total = 0; files=""}; {total += $5 files="\n" files $9} END{print total "files:" files}'`

echo $output 给出以下内容:

800 文件名1 文件名2 文件名3

我想让它显示:

800
filename1
filename2
filename3

我不明白为什么这些行没有拆分成新行?

最佳答案

当你不在 shell 中引用你的变量时,空白,包括换行符会被折叠,所以一个简单的修复你所做的就是使用 echo "$output"

也就是说,我建议不要使用 ls -l 来获取您的文件名及其大小,因为该工具不是为解析而设计的。当您有一个有趣的文件名时,任何基于列的方法都会失败。

使用 GNU stat 允许您获取文件大小并控制输出,使用空字节 \0 使名称可以安全解析:

stat --printf '%s\0%n\0' * | awk -v RS='\0' '
NR % 2 { total += $0; next } # add to total on odd lines, skip to next line
{ files[++n] = $0 } # save file names on other (even) lines
END { print total, "bytes, files:"; for (i = 1; i <= n; ++i) print files[i] }'

如果您不能使用 stat --printf,那么您可以使用 stat -c 并希望没有人在文件名中添加换行符:

stat -c '%s %n' * | awk '{ total += $1; files[NR] = substr($0, length($1) + 2) } 
END { print total, "bytes, files:"; for (i = 1; i <= NR; ++i) print files[i] }'

第一个字段包含名称,该行的其余部分是文件名,因此 substr 用于获取该部分。

作为参数传递给 stat* 由 shell 扩展为当前目录中文件的完整列表。您可以通过传递 /path/to/dir/* 或首先 cding 到目的地来获取另一个目录中的文件。您也可以使用循环,例如:

for dir in dir1 dir2 dir3; do
( cd "$dir" && stat -c '%s %n' * | awk '...')
done

在这里,我使用了 ( subshel​​l ) 作为在每次循环迭代后返回到原始目录的惰性方式。

关于linux - Awk:如何用新行构建一个字符串变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44152482/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com