例如,给定以下内容:
USCAGoleta9311734.5021-120.1287855805
我想要仅提取:
US
例如,给定以下内容:
USCAGoleta9311734.5021-120.1287855805
我想要仅提取:
US
如果你正在使用 bash
shell,并且根据你的评论似乎是这样,那么可能是最有效的方法是使用参数扩展的子字符串变体:
pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US
这将把 long
的前两个字符赋值给 short
。如果 long
长度小于两个字符,则 short
将与之相同。
如果你需要频繁地执行此操作(如你所提到的每个报告执行 50,000 次),那么使用这种在 shell 中的方法通常更好,因为它没有进程创建开销。所有使用外部程序的解决方案都会受到该开销的影响。
如果你还想确保最小长度,可以先用类似下面的方式将其填充:
pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.
这会确保长度小于两个字符的任何内容在右侧用句点(或其他字符,只需在创建tmpstr
时更改使用的字符)进行填充。不清楚您是否需要此功能,但出于完整性考虑,我认为应该加上。
话虽如此,有许多使用外部程序(例如,如果您没有bash
可用)完成此操作的方法,其中一些方法包括:
short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ($0, 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*/\1/')
对于单行字符串,前两个方法(cut
和 head
)是相同的 - 它们基本上只会返回前两个字符。它们之间的区别在于 cut
会给你每一行的前两个字符,而 head
会给你整个输入的前两个字符。
第三个方法使用 awk
子字符串函数提取前两个字符,第四个方法使用 sed
捕获组(使用()
和 \1
)捕获前两个字符并用它们替换整行内容。它们都类似于 cut
- 它们会提供输入中每一行的前两个字符。
如果您确定输入是单行,则这些内容都无关紧要,它们具有相同的效果。
printf '%s'
而不是echo
,以防字符串中有奇怪的字符:https://dev59.com/t5zha4cB1Zd3GeqPBje1#40423558 对于POSIX迷,head -c
不是POSIX标准,cut -c
和awk substr
是,sed \1
不确定。 - Ciro Santilli OurBigBook.com最简单的方法是:
${string:position:length}
这个从$string
的$position
位置提取$length
个字符的子串,是Bash内置函数,不需要使用awk或sed。
你已经得到了几个很好的答案,我会选择使用Bash内置函数,但是由于你询问了sed
和awk
,而且(几乎)没有人提供基于它们的解决方案,所以我给你提供以下内容:
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,1,2)}'
和
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'
awk
的用法非常显然,但这里是对 sed
代码的解释:
substr($0,1,2)
。 - user8017719index()
保持一致,最好使用1。回答已更新。 - Dennis Williamson只需使用grep:
echo 'abcdef' | grep -Po "^.." # ab
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
这里使用了"最小前缀"参数扩展来删除前两个字符(即${var#??}
部分),然后使用"最小后缀"参数扩展(${var%
部分)从原始值中删除除第一个两个字符之外的所有字符串。
这种方法先前在答案中描述了“Shell = Check if variable begins with #”问题。该答案还描述了几种类似的参数扩展方法,可以在略微不同的上下文中使用,适用于原始问题所涉及的上下文。
echo "${var%"${var#??}"}"
,那就更好了。(参考 - https://www.shellcheck.net/wiki/SC2295) - midnite如果你正在使用 bash
,你可以这样说:
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
printf
:$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US
colrm — 从文件中删除列
要保留前两个字符,只需从第三列开始删除即可。
cat file | colrm 3
使用:
sed 's/.//3g'
或者
awk NF=1 FPAT=..
或者
perl -pe '$_=unpack a2'
仅仅是为了好玩,我会添加一些虽然过于复杂和无用的内容,但它们并未被提到:
head -c 2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
echo 'USCAGoleta9311734.5021-120.1287855805' | dd bs=2 count=1 status=none
sed -e 's/^\(.\{2\}\).*/\1/;' <( echo 'USCAGoleta9311734.5021-120.1287855805')
cut -c 1-2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
python -c "print(r'USCAGoleta9311734.5021-120.1287855805'[0:2])"
ruby -e 'puts "USCAGoleta9311734.5021-120.1287855805"[0..1]'