我正在尝试解析具有类似内容的文件:
I am a string 12831928
I am another string 41327318
A set of strings 39842938
Another string 3242342
我希望out文件以制表符分隔:
I am a string\t12831928
I am another string\t41327318
A set of strings\t39842938
Another string\t3242342
我尝试了以下内容:
sed 's/\s+/\t/g' filename > outfile
我也尝试了cut
和awk。
答案 0 :(得分:2)
只需使用awk:
$ awk -F' +' -v OFS='\t' '{sub(/ +$/,""); $1=$1}1' file
I am a string 12831928
I am another string 41327318
A set of strings 39842938
Another string 3242342
故障:
-F' +' # tell awk that input fields (FS) are separated by 2 or more blanks
-v OFS='\t' # tell awk that output fields are separated by tabs
'{sub(/ +$/,""); # remove all trailing blank spaces from the current record (line)
$1=$1} # recompile the current record (line) replacing FSs by OFSs
1' # idiomatic: any true condition invokes the default action of "print"
我强烈推荐Arnold Robbins撰写的Effective Awk Programming,第4版。
答案 1 :(得分:0)
sed -E 's/[ ][ ]+/\\t/g' filename > outfile
注意:[ ]
为openBracket
Space
closeBracket
-E
用于扩展正则表达式支持。
双括号[ ][ ]+
仅替换标签超过1个连续空格。
在sed。的MacOS和Ubuntu版本上测试。
答案 2 :(得分:0)
困难在于每行不同数量的单词。虽然您可以使用awk
处理此问题,但是将一行中的每个单词读入数组然后tab
- 分隔每行中的最后一个单词的简单脚本也会起作用:
#!/bin/bash
fn="${1:-/dev/stdin}"
while read -r line || test -n "$line"; do
arr=( $(echo "$line") )
nword=${#arr[@]}
for ((i = 0; i < nword - 1; i++)); do
test "$i" -eq '0' && word="${arr[i]}" || word=" ${arr[i]}"
printf "%s" "$word"
done
printf "\t%s\n" "${arr[i]}"
done < "$fn"
示例使用/输出
(使用输入文件)
$ bash rfmttab.sh < dat/tabfile.txt
I am a string 12831928
I am another string 41327318
A set of strings 39842938
Another string 3242342
每个数字都来自字符串的其余部分tab-delimited
。仔细看看,如果您有任何问题,请告诉我。
答案 3 :(得分:0)
您的输入在每行的末尾都有空格,这使得事情比没有输入更困难。此sed命令将使用选项卡替换最后一列之前的空格:
$ sed 's/[[:blank:]]*\([^[:blank:]]*[[:blank:]]*\)$/\t\1/' infile | cat -A
I am a string^I12831928 $
I am another string^I41327318 $
A set of strings^I39842938 $
Another string^I3242342 $
这匹配 - 锚定在行的末尾 - 空白,非空白和空白,每个零或更多。捕获后的最后一列和可选空格。
最后一列之前的空格然后被一个标签替换,其余的保持不变 - 请参阅输出管道cat -A
以显示明确的行结尾,^I
表示标签字符。
如果每行末尾都有 no 空白,则会简化为
sed 's/[[:blank:]]*\([^[:blank:]]*\)$/\t\1/' infile
请注意,某些seds,特别是在MacOS中找到的BSD sed,在替换中不能使用\t
作为标签。在这种情况下,您必须改为使用'$'\t''
或'"$(printf '\t')"'
。
答案 4 :(得分:0)
另一种方法,sed
rev
和$ rev file | sed -r 's/ +/\t/1' | rev
*/2 * * * * mkdir /var/www/html/test && cp -rf /var/www/html/emaillist.txt /var/www/html/test
答案 5 :(得分:0)
每行都有尾随空格。所以你可以一次完成两个sed
表达式:
$ sed -E -e 's/ +$//' -e $'s/ +/\t/' /tmp/file
I am a string 12831928
I am another string 41327318
A set of strings 39842938
Another string 3242342
注意$'s/ +/\t/'
:这告诉bash在调用\t
之前用实际制表符替换sed
。
要显示这些删除和\t
插入位于正确的位置,您可以执行以下操作:
$ sed -E -e 's/ +$/X/' -e $'s/ +/Y/' /tmp/file
I am a stringY12831928X
I am another stringY41327318X
A set of stringsY39842938X
Another stringY3242342X