我有一个制表符delim file1,其中第一列看起来像
1
1
6
6
6
1A
1A
1B
2
2
2
2
3
4
4A
Z
Z
我想替换,以便1 = 1, 1A = 2, 1B = 3, 2 = 4, 3 = 5, 4 = 6, 4A = 7, 6 = 8, Z = 9
输出应为
1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
我有其他帖子说,为避免累积替换,我应该从较大的值到较小的值进行工作,并使用以下方法进行多次替换:
sed -e 's/a/b/g ; s/b/d/g' file
但是我有60个替补。
有没有一种方法可以循环执行此操作或替代其他替代方法
请注意,每个元素重复不同的时间,它们可以是数字和字符,但是我将它们全部替换为数字1-60,并且以预定义的顺序而不是按照它们出现的顺序。我的文件中还有其他具有相同字符的列,但是我只想替换第一列中的内容。
答案 0 :(得分:3)
使用以下搜索和替换字符串创建映射文件:
cat mapping
1 1
1A 2
1B 3
2 4
3 5
4 6
4A 7
6 8
Z 9
然后只需使用此awk
即可在单个命令中获取所有替换项:
awk 'BEGIN{FS=OFS="\t"} NR == FNR{key[$1]=$2; next} $1 in key{$1=key[$1]} 1' mapping file
1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
答案 1 :(得分:1)
能否请您尝试以下操作(如果您用TAB分隔了Input_file,并且也需要以TAB格式输出,请在unset($_SESSION[datos_form][__step__]);
部分中添加其他FS=OFS="\t"
。
BEGIN
答案 2 :(得分:1)
对于单个数字前缀,无需手动映射即可使用
$ awk 'NR==FNR {a[$1]; next}
FNR==1 {asorti(a,b); for(k in b) c[b[k]]=k}
{print c[$1]}' file{,}
1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
请注意,将6映射为8,而不是示例输出中的4。
答案 3 :(得分:1)
这可能对您有用(GNU sed):
sed -E 's/$/\n:1=1:1A=2:1B=3:2=4:3=5:4=6:4A=7:6=8:Z=9/;s/^(\S+)(.*)\n.*:\1=([^:]*).*/\3\2/;P;d' file
将查找表追加到每一行,并使用模式匹配和向后引用将第一列转换为所需的字符串。
没有匹配查找的行将不会更改。
答案 4 :(得分:1)
由于您只想使用从1开始的连续数字作为替换,因此您所需要做的就是:
awk '
BEGIN {
split("1 1A 1B 2 3 4 4A 6 Z",tmp)
for (i in tmp) {
map[tmp[i]] = i
}
FS = OFS = "\t"
}
$1 in map { $1 = map[$1] }
1' file
1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
1