Bash技巧:把變量賦值爲換行符,判斷文件是否以換行符結尾

把變量賦值爲換行符

在 bash 中,若是要把變量賦值爲換行符,寫爲 '\n' 沒有效果,須要寫爲 $'\n'。具體舉例以下:bash

$ newline='\n'
$ echo $newline
\n
$ newline=$'\n'
$ echo $newline

能夠看到,把 newline 變量賦值爲 'n',獲得的是 n 這個字符串,而不是換行符自身。code

這是 bash 和 C 語言不同的地方。
在 C 語言中,'n' 對應換行符自身,只有一個字符;而 "n" 對應一個字符串。
可是在 bash 中,'n' 也是對應一個字符串。orm

newline 賦值爲 $'\n',就能獲取到換行符自身。查看 man bash 對這個寫法的說明以下:ci

Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows:
\n     new line
    \r     carriage return
    \t     horizontal tab
    \'     single quote
The expanded result is single-quoted, as if the dollar sign had not been present.

即,$'string' 這個寫法能夠使用 C 語言的轉義字符來獲取到對應的字符自身。rem

判斷文件的最後一行是否以換行符結尾

在 Linux 中,能夠使用下面命令來判斷文件的最後一行是否以換行符結尾:字符串

test -n "$(tail filename -c 1)"

這裏使用 tail filename -c 1 命令獲取到 filename 文件的最後一個字符。string

實際使用時,須要把 filename 換成具體要判斷的文件名。it

tail 命令能夠獲取文件末尾的內容。它的 -c 選項指定要獲取文件末尾的多少個字節。io

查看 man tail 對 -c 選項的說明以下:ast

-c, --bytes=K

output the last K bytes; alternatively, use -c +K to output bytes starting with the Kth of each file.

即,tail -c 1 命令指定獲取所給文件的最後一個字符。

獲取到文件的最後一個字符後,要判斷該字符是否是換行符。這裏不能直接判斷該字符是否等於換行符,而是要判斷該字符是否爲空。

緣由在於,使用 $(tail filename -c 1) 命令替換來獲取內部命令的輸出結果時,bash 會去掉末尾的換行符。

因此當文件的最後一行以換行符結尾時,$(tail filename -c 1) 命令替換會去掉獲取到的換行符,最終結果爲空,並不會返回換行符自身。

查看 man bash 對命令替換(command substitution)的說明以下:

Command substitution allows the output of a command to replace the command name. There are two forms:
$(command)
    or
        `command`
Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting.

能夠看到,通過命令替換後,會去掉末尾的換行符。

因爲 $(tail filename -c 1) 命令替換會去掉末尾的換行符,這裏使用 test -n 來判斷最終結果是否爲空字符串。

若是文件最後一行以換行符結尾,那麼 $(tail filename -c 1) 的結果爲空,test -n 命令會返回 1,也就是 false。

若是文件最後一行沒有以換行符結尾,那麼 $(tail filename -c 1) 的結果不爲空,test -n 命令會返回 0,也就是 true。

能夠根據實際須要,改用 test -z 來判斷。若是文件最後一行以換行符結尾,$(tail filename -c 1) 的結果爲空,test -z 命令會返回 0,也就是 true。

相關文章
相關標籤/搜索