![SED 或其他工具删除第一个空格之后直到 `|` 的所有内容](https://linux22.com/image/900821/SED%20%E6%88%96%E5%85%B6%E4%BB%96%E5%B7%A5%E5%85%B7%E5%88%A0%E9%99%A4%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%A9%BA%E6%A0%BC%E4%B9%8B%E5%90%8E%E7%9B%B4%E5%88%B0%20%60%7C%60%20%E7%9A%84%E6%89%80%E6%9C%89%E5%86%85%E5%AE%B9.png)
我正在处理一个小的 bash 片段:
$ stat --printf=%A\|%U\|%G\|%s\|%y\|%N'\n' /usr/src/linux-headers-4.4.0-124/zfs/cmd/zhack
drwxr-xr-x|root|root|4096|2018-05-17 05:54:49.361904361 -0600|'/usr/src/linux-headers-4.4.0-124/zfs/cmd/zhack
日期太丑了,所以我想用sed
(或任何可行的方法)删除第一个空格之后到下一个空格的所有内容|
。当然,如果stat
命令可以正常打印日期,那也可以!
对sed
接受挑战的人有什么建议吗?
答案1
使用 sed:
$ stat --printf='%A|%U|%G|%s|%y|%N\n' /etc/profile | sed 's/ [^|]*//'
-rw-r--r--|root|root|575|2015-10-23|'/etc/profile'
它只是将空格后跟的非|
字符替换为空。
答案2
和bash
$ a=$(stat -c'%A|%U|%G|%s|%y|%N' /etc/profile) ; echo ${a/ *|/|}
-rw-r--r--|root|root|575|2017-09-22|'/etc/profile'
这是bash
的参数扩展,更准确地说是模式替换,参见man bash
/扩展/参数扩展。我还自由地稍微简化了您的命令行。
和awk
$ stat -c'%A|%U|%G|%s|%y|%N' /etc/profile | awk -v{O,}FS=\| '{sub(/ [^|]+/,"",$5)}1'
-rw-r--r--|root|root|575|2017-09-22|'/etc/profile'
这稍微长一点,但实际上是最准确的解决方案:它明确改变了第五个字段仅有的因此文件和用户名中的空格(期待意外)不会有问题。比较:
$ a="-rw-r--r--|ro ot|ro ot|575|2017-09-22 17:35:19.337510248 +0200|'/etc/pro fi|le'"
$ sed 's/ [^|]*//' <<<$a
-rw-r--r--|ro|ro ot|575|2017-09-22 17:35:19.337510248 +0200|'/etc/pro fi|le'
$ echo ${a/ *|/|}
-rw-r--r--|ro|le'
$ awk -v{O,}FS=\| '{sub(/ [^|]+/,"",$5)}1' <<<$a
-rw-r--r--|ro ot|ro ot|575|2017-09-22|'/etc/pro fi|le'
用户名不应该包含竖线|
- 不过,你也可以处理这种情况:
$ b=$(awk -F\| '{print NF-1}' <<<"ro||ot") # how many bars again?
$ a="-rw-r--r--|ro||ot|ro||ot|575|2017-09-22 17:35:19.337510248 +0200|'/etc/pro fi|le'"
$ awk -v{O,}FS=\| '{sub(/ [^|]+/,"",$'$((5+b*2))')}1' <<<$a
-rw-r--r--|ro||ot|ro||ot|575|2017-09-22|'/etc/pro fi|le'