Replacing/removing 文件中列之间的多余白色 space
Replacing/removing excess white space between columns in a file
我正在尝试解析具有类似内容的文件:
I am a string 12831928
I am another string 41327318
A set of strings 39842938
Another string 3242342
我希望输出文件以制表符分隔:
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。
sed -E 's/[ ][ ]+/\t/g' filename > outfile
注意:[ ]
是 openBracket
Space
closeBracket
-E
用于扩展正则表达式支持。
双括号[ ][ ]+
仅用于替换连续1个以上的制表符space。
在 MacOS 和 Ubuntu 版本的 sed 上测试。
困难在于单词数量的变化 per-line。虽然您可以使用 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"
例子Use/Output
(使用您的输入文件)
$ 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
。仔细阅读,如果您有任何问题,请告诉我。
您输入的每行末尾都有空格,这使事情变得比没有空格更困难。此 sed 命令将用制表符替换最后一列之前的空格:
$ sed 's/[[:blank:]]*\([^[:blank:]]*[[:blank:]]*\)$/\t/' infile | cat -A
I am a string^I12831928 $
I am another string^I41327318 $
A set of strings^I39842938 $
Another string^I3242342 $
这匹配 - 锚定在行尾 - 空白,non-blanks 和再次空白,每个零个或多个。最后一列和捕获后的可选空白。
最后一列之前的空格随后被单个制表符替换,其余部分保持不变 – 请参阅管道输出到 cat -A
以显示明确的行结尾和 ^I
制表符。
如果每行末尾没有个空格,则简化为
sed 's/[[:blank:]]*\([^[:blank:]]*\)$/\t/' infile
请注意,某些 seds,尤其是 MacOS 中的 BSD sed,不能在替换中使用 \t
作为制表符。在这种情况下,您必须改用 '$'\t''
或 '"$(printf '\t')"'
。
另一种方法,gnu
sed
和 rev
$ rev file | sed -r 's/ +/\t/1' | rev
只需使用 awk:
$ awk -F' +' -v OFS='\t' '{sub(/ +$/,""); =}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)
=} # 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 版。
每行都有尾随空格。所以你可以像这样一次做两个 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 在调用 sed
之前用实际制表符替换 \t
。
要显示这些删除和 \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
简单且无隐形语义字符代码中:
perl -lpe 's/\s+$//; s/\s\s+/\t/' filename
解释:
Options:
-l: remove LF during processing (in this case)
-p: loop over records (like awk) and print
-e: code follows
Code:
remove trailing whitespace
change two or more whitespace to tab
已在 OP 数据上进行测试。为了保持一致性,删除了尾随空格。
我正在尝试解析具有类似内容的文件:
I am a string 12831928
I am another string 41327318
A set of strings 39842938
Another string 3242342
我希望输出文件以制表符分隔:
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。
sed -E 's/[ ][ ]+/\t/g' filename > outfile
注意:[ ]
是 openBracket
Space
closeBracket
-E
用于扩展正则表达式支持。
双括号[ ][ ]+
仅用于替换连续1个以上的制表符space。
在 MacOS 和 Ubuntu 版本的 sed 上测试。
困难在于单词数量的变化 per-line。虽然您可以使用 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"
例子Use/Output
(使用您的输入文件)
$ 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
。仔细阅读,如果您有任何问题,请告诉我。
您输入的每行末尾都有空格,这使事情变得比没有空格更困难。此 sed 命令将用制表符替换最后一列之前的空格:
$ sed 's/[[:blank:]]*\([^[:blank:]]*[[:blank:]]*\)$/\t/' infile | cat -A
I am a string^I12831928 $
I am another string^I41327318 $
A set of strings^I39842938 $
Another string^I3242342 $
这匹配 - 锚定在行尾 - 空白,non-blanks 和再次空白,每个零个或多个。最后一列和捕获后的可选空白。
最后一列之前的空格随后被单个制表符替换,其余部分保持不变 – 请参阅管道输出到 cat -A
以显示明确的行结尾和 ^I
制表符。
如果每行末尾没有个空格,则简化为
sed 's/[[:blank:]]*\([^[:blank:]]*\)$/\t/' infile
请注意,某些 seds,尤其是 MacOS 中的 BSD sed,不能在替换中使用 \t
作为制表符。在这种情况下,您必须改用 '$'\t''
或 '"$(printf '\t')"'
。
另一种方法,gnu
sed
和 rev
$ rev file | sed -r 's/ +/\t/1' | rev
只需使用 awk:
$ awk -F' +' -v OFS='\t' '{sub(/ +$/,""); =}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)
=} # 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 版。
每行都有尾随空格。所以你可以像这样一次做两个 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 在调用 sed
之前用实际制表符替换 \t
。
要显示这些删除和 \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
简单且无隐形语义字符代码中:
perl -lpe 's/\s+$//; s/\s\s+/\t/' filename
解释:
Options:
-l: remove LF during processing (in this case)
-p: loop over records (like awk) and print
-e: code follows
Code:
remove trailing whitespace
change two or more whitespace to tab
已在 OP 数据上进行测试。为了保持一致性,删除了尾随空格。