Bash - 提取 2 个字符之间的子字符串
Bash - extract substring between 2 characters
字符串可能如下:
1cd9f3e7d...7b486fef4 lineage-15.1-caf-8952 -> github/lineage-15.1-caf-8952 (forced update)
8648766e0..6e7faf655 lineage-15.1-caf-8952 -> github/lineage-15.1-caf-8952
e60d05ad9..784fbae86 lineage-15.1 -> github/lineage-15.1
b651b35..673d421 lineage-15.1 -> github/lineage-15.1
0a5232e..a36e212 lineage-15.1 -> github/lineage-15.1
f94851a03e2..d2ff869bdf6 lineage-15.1 -> github/lineage-15.1
769dd0439..88d4d3adc lineage-15.1-caf-8952 -> github/lineage-15.1-caf-8952
a0553bd5f1a..69748ff0d0f lineage-15.1 -> github/lineage-15.1
dbe2868..ab03f89 lineage-15.1 -> github/lineage-15.1
7caf61f4e..2de89a8d9 lineage-15.1 -> github/lineage-15.1
我需要提取 .
abd l
个字符之间的字符串。如果我对上述每个字符串执行 sed:
awk -F"[.l]" '{print }'
结果 - 第一个字符串为空:
6e7faf655
784fbae86
673d421
a36e212
d2ff869bdf6
88d4d3adc
69748ff0d0f
ab03f89
2de89a8d9
如果我这样做:
awk -F"[.l]" '{print }'
结果 - 第一个子串没问题,其余的都移位了:
7b486fef4
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
无论源字符串格式是什么,如何处理它以始终获得我想要的子字符串?
选一个你喜欢的:
sed
解法:
sed -E 's/^[^.]+\.{1,}([^.[:space:]]+).*//' file
awk
解法:
awk '{ sub(/.*\.{1,}/, "", ); print }' file
输出:
7b486fef4
6e7faf655
784fbae86
673d421
a36e212
d2ff869bdf6
88d4d3adc
69748ff0d0f
ab03f89
2de89a8d9
$ grep -oP '(?<=\.\.)\w+' file
7b486fef4
6e7faf655
784fbae86
673d421
a36e212
d2ff869bdf6
88d4d3adc
69748ff0d0f
ab03f89
2de89a8d9
修改OP的尝试
$ awk -F'[.]+| ' '{print }' ip.txt
7b486fef4
6e7faf655
784fbae86
673d421
a36e212
d2ff869bdf6
88d4d3adc
69748ff0d0f
ab03f89
2de89a8d9
-F'[.]+| '
字段分隔符是连续的点或 space 字符。所以,获得第二个领域就足够了
- 这里也可以用
-F'[. ]+'
cut -d ' ' -f 1 FILE | rev | cut -d '.' -f 1 | rev
解释:
- 首先
cut
提取第一部分(直到第一个 space)。
- 比我们使用的
rev
所以每一行都颠倒了所以最后一个字段现在是第一个。
- 比我们再次使用
cut
来提取第一列直到 .
个字符。
- 最后
rev
再次恢复正确的字符顺序。
字符串可能如下:
1cd9f3e7d...7b486fef4 lineage-15.1-caf-8952 -> github/lineage-15.1-caf-8952 (forced update)
8648766e0..6e7faf655 lineage-15.1-caf-8952 -> github/lineage-15.1-caf-8952
e60d05ad9..784fbae86 lineage-15.1 -> github/lineage-15.1
b651b35..673d421 lineage-15.1 -> github/lineage-15.1
0a5232e..a36e212 lineage-15.1 -> github/lineage-15.1
f94851a03e2..d2ff869bdf6 lineage-15.1 -> github/lineage-15.1
769dd0439..88d4d3adc lineage-15.1-caf-8952 -> github/lineage-15.1-caf-8952
a0553bd5f1a..69748ff0d0f lineage-15.1 -> github/lineage-15.1
dbe2868..ab03f89 lineage-15.1 -> github/lineage-15.1
7caf61f4e..2de89a8d9 lineage-15.1 -> github/lineage-15.1
我需要提取 .
abd l
个字符之间的字符串。如果我对上述每个字符串执行 sed:
awk -F"[.l]" '{print }'
结果 - 第一个字符串为空:
6e7faf655
784fbae86
673d421
a36e212
d2ff869bdf6
88d4d3adc
69748ff0d0f
ab03f89
2de89a8d9
如果我这样做:
awk -F"[.l]" '{print }'
结果 - 第一个子串没问题,其余的都移位了:
7b486fef4
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
ineage-15
无论源字符串格式是什么,如何处理它以始终获得我想要的子字符串?
选一个你喜欢的:
sed
解法:
sed -E 's/^[^.]+\.{1,}([^.[:space:]]+).*//' file
awk
解法:
awk '{ sub(/.*\.{1,}/, "", ); print }' file
输出:
7b486fef4
6e7faf655
784fbae86
673d421
a36e212
d2ff869bdf6
88d4d3adc
69748ff0d0f
ab03f89
2de89a8d9
$ grep -oP '(?<=\.\.)\w+' file
7b486fef4
6e7faf655
784fbae86
673d421
a36e212
d2ff869bdf6
88d4d3adc
69748ff0d0f
ab03f89
2de89a8d9
修改OP的尝试
$ awk -F'[.]+| ' '{print }' ip.txt
7b486fef4
6e7faf655
784fbae86
673d421
a36e212
d2ff869bdf6
88d4d3adc
69748ff0d0f
ab03f89
2de89a8d9
-F'[.]+| '
字段分隔符是连续的点或 space 字符。所以,获得第二个领域就足够了- 这里也可以用
-F'[. ]+'
- 这里也可以用
cut -d ' ' -f 1 FILE | rev | cut -d '.' -f 1 | rev
解释:
- 首先
cut
提取第一部分(直到第一个 space)。 - 比我们使用的
rev
所以每一行都颠倒了所以最后一个字段现在是第一个。 - 比我们再次使用
cut
来提取第一列直到.
个字符。 - 最后
rev
再次恢复正确的字符顺序。