从STDIN重新格式化awk和sed并执行

时间:2014-11-01 13:33:11

标签: linux shell awk sed

这只是我经常遇到的一个例子: 我想将所有.bash_histories复制到一个目录。

grep "/bin/bash" /etc/passwd | awk -F: '{ print "cp " $6"/.bash_history /backup" $6 ".bash_history" }

输出:

cp /home/peter/.bash_history /backup/home/peter/.bash_history
cp /home/john/.bash_history /backup/home/john/.bash_history

我想要的是这样的输出:

cp /home/peter/.bash_history /backup/_home_peter_.bash_history
cp /home/john/.bash_history /backup/_home_john_.bash_history

此输出将被执行。

(这不是特别关于这个问题,但一般来说如何重新格式化awk和sed并执行新创建的命令行,而不是真正为它创建脚本)

3 个答案:

答案 0 :(得分:0)

获取类似输出的awk脚本将是

grep "/bin/bash" /etc/passwd |head -2 | awk -F: '{ print "cp " $6 "/.bash_history backup/_home_"$1".bash_history" }'

提供类似

的输出
cp /root/.bash_history backup/_home_root.bash_history
cp /home/xxx/.bash_history backup/_home_xxx.bash_history

现在为了执行命令,system()中的awk函数会有所帮助

system(command)将执行任何命令,并返回值作为命令的退出状态。

上述脚本可以修改为

grep "/bin/bash" /etc/passwd |head -2 | awk -F: '{ system("cp " $6 "/.bash_history backup/_home_"$1".bash_history;") }'

试运行:

$ grep "/bin/bash" /etc/passwd |head -2 | awk -F: '{ system("cp " $6 "/.bash_history backup/_home_"$1".bash_history;") }'
$ ls backup/
_home_xxx.bash_history  _home_root.bash_history

PS:建议不要在根文件夹中创建目录。所以我故意将脚本中的/backup替换为backup

此外,为了使脚本成功,必须事先创建backup文件夹。

答案 1 :(得分:0)

getent passwd | grep \/bin\/bash | cut -d ":" -f 6 | while read a; do eval "cp $a/.bash_history /backup/$(echo $a | sed 's#/#_#g')_.bash_history"; done

这使用getent来获取passwd文件,cut会像awk语句一样获取第6个字段,然后逐行读取每个条目并构建字符串并使用eval执行它。

答案 2 :(得分:0)

getent passwd | grep \/bin\/bash | cut -d ":" -f 6 | while read a; do eval "cp $a/.bash_history /backup/$(echo $a | sed 's#/#_#g')_.bash_history"; done

工作完美!问题解决了!