【问题标题】:Convert line-endings for whole directory tree (Git)转换整个目录树的行尾(Git)
【发布时间】:2011-10-27 10:42:01
【问题描述】:

以下情况:

我正在使用运行 OS X 的 Mac 并最近加入了一个项目,该项目的成员到目前为止都使用 Windows。我的首要任务之一是在 Git 存储库中设置代码库,因此我从 FTP 中提取了目录树并尝试将其检入到我在本地准备的 Git 存储库中。当试图这样做时,我得到的只是这个

fatal: CRLF would be replaced by LF in blog/license.txt.

由于这会影响“blog”文件夹下的所有文件,我正在寻找一种方法来方便地将树中的所有文件转换为 Unix 行尾。是否有开箱即用的工具或者我自己编写脚本?

作为参考,我关于行尾的 Git 配置:

core.safecrlf=true
core.autocrlf=input

【问题讨论】:

    标签: git line-endings


    【解决方案1】:

    如果使用 sed,这里有一个解决方案:

    find . -type f -exec sed -i 's/\r$//' {} \;
    

    -i 代表就地,如果您还想创建备份,请使用-i.bak

    's/\r$//' 将替换每行末尾的所有回车符(\r

    【讨论】:

    • 当你在 git 仓库中运行它时,你可能会看到sed: cannot rename ./.git/objects/16/sed68Vezl: Permission denied。在这种情况下,您必须排除 .git 文件夹。
    • 注意不要对二进制文件运行此命令,例如.mp4.jpg.png,因为它会损坏它们。
    【解决方案2】:

    dos2unix 为你做这件事。相当直接的过程。
    dos2unix filename

    感谢 toolbear,这是一个递归替换行尾并正确处理空格、引号和 shell 元字符的单行代码。

    find . -type f -exec dos2unix {} \;

    如果您使用的是 dos2unix 6.0 二进制文件将被忽略。

    【讨论】:

    • find blog -type f | xargs dos2unix 应该更快。您也不需要-name *.*,除非您特别想要名称中某处带有句点的文件。这是一个 windows glob,而不是一个 *nix 。
    • 如果 find 匹配路径中包含空格、引号或其他 shell 元字符的任何文件,则将 find 管道连接到 xargs 将失败。至少使用find blog -type f -print0 | xargs -0 dos2unix 来处理空格的情况。您必须使用find-exec 而不是管道以避免引号等。dos2unix 手册页未指定在二进制文件上调用它时的行为。如果它将 CRLF 转换为二进制文件,则会损坏它们。请参阅我的答案以获得更安全但更长的替代方案。
    • @lukmdo 这不是安装在 centos 6.4 上的版本.....它确实破坏了它们....相反我不得不从这里rpmfind.net/linux/rpm2html/search.php?query=dos2unix
    • 如果可能的话,如何使用这种方法忽略目录?
    • @kajibu 手册页可以更好地解释它:“表达式必须以分号结尾 (;)。如果从 shell 调用 find ,如果 shell 将其视为控制运算符,则可能需要引用分号。如果字符串 {} 出现在实用程序名称或参数中的任何位置,则将其替换为当前文件的路径名。”
    【解决方案3】:

    在 OS X 上,这对我有用:

    find ./ -type f -exec perl -pi -e 's/\r\n|\n|\r/\n/g' {} \;
    

    警告:请在执行此命令之前备份您的目录。

    【讨论】:

    • 只想指出这破坏了我的 git 存储库。我再次尝试在运行之前移出 .git 文件夹,然后再将其移回,取得了更好的成功。
    • 我还要注意,这不排除二进制文件,因此它将例如损坏您的 jpg。
    【解决方案4】:
    find . -not \( -name .svn -prune -o -name .git -prune \) -type f -exec perl -pi -e 's/\r\n|\n|\r/\n/g' {} \;
    

    这更安全,因为它可以避免破坏你的 git repo。将 .git、.svn 添加或替换为 .bzr、.hg 或您使用的任何源代码控制到 not 列表。

    【讨论】:

    • 如果您不必安装类似 dos2unix 的任何东西,这是最好的答案。允许排除文件类型并避免损坏源代码文件。
    【解决方案5】:

    假设您有 GNU grepperl,这将在当前目录下的非二进制文件中递归地将 CRLF 转换为 LF:

    find . -type f -exec grep -qIP '\r\n' {} ';' -exec perl -pi -e 's/\r\n/\n/g' {} '+'
    

    工作原理

    在当前目录下递归查找;将. 更改为blogwhatev 子目录以限制替换:

    find .
    

    只匹配常规文件:

      -type f
    

    测试文件是否包含 CRLF。排除二进制文件。为每个常规文件运行 grep 命令。这就是排除二进制文件的代价。如果您有旧的grep,您可以尝试使用file 命令构建测试:

      -exec grep -qIP '\r\n' {} ';'
    

    用 LF 替换 CRLF。 '+' 和第二个 -exec 告诉 find 累积匹配文件并将它们传递给命令的一个(或尽可能少的)调用——比如管道到xargs,但如果文件路径包含空格、引号或其他 shell 元字符。 -pi 中的 i 告诉 perl 修改文件。您可以在这里使用sedawk 进行一些工作,并且您可能会将“+”更改为“;”并为每个匹配调用一个单独的过程:

      -exec perl -pi -e 's/\r\n/\n/g' {} '+'
    

    【讨论】:

    • 如果它对任何人有帮助:grep -qIP '\r\n' 永远不会匹配我 CentOS 系统上的任何东西。将其更改为 grep -qIP '\r$' 有效。
    • 讨厌在 cmets 中询问,但有没有办法排除像 node_modules 这样的文件夹?
    • @datatype_void 查看stackoverflow.com/questions/4210042/…,了解如何修改命令的find 部分以排除目录。他们建议使用-path,但您也可以使用-regex-iregex,即-not -regex '.*/node_modules/.*',它将在任何深度排除node_modules
    • 对不起,如果我以 regexbash 菜鸟的身份出现,但多重排除呢,例如 node_moduledist
    • 我还需要按照@SteveOnorato 的建议在 Linux Mint 上使用“\r$”。奇怪
    【解决方案6】:

    这里有一个更好的选择:Swiss File Knife。它以递归方式跨子目录工作,并正确处理空格和特殊字符。

    你所要做的就是:

    sfk remcr -dir your_project_directory
    

    奖励:sfk 还进行了许多其他转换。完整列表见下文:

    SFK - The Swiss File Knife File Tree Processor.
    Release 1.6.7 Base Revision 2 of May  3 2013.
    StahlWorks Technologies, http://stahlworks.com/
    Distributed for free under the BSD License, without any warranty.
    
    type "sfk commandname" for help on any of the following.
    some commands require to add "-help" for the help text.
    
       file system
          sfk list       - list directory tree contents.
                           list latest, oldest or biggest files.
                           list directory differences.
                           list zip jar tar gz bz2 contents.
          sfk filefind   - find files by filename
          sfk treesize   - show directory size statistics
          sfk copy       - copy directory trees additively
          sfk sync       - mirror tree content with deletion
          sfk partcopy   - copy part from a file into another one
          sfk mkdir      - create directory tree
          sfk delete     - delete files and folders
          sfk deltree    - delete whole directory tree
          sfk deblank    - remove blanks in filenames
          sfk space [-h] - tell total and free size of volume
          sfk filetime   - tell times of a file
          sfk touch      - change times of a file
    
       conversion
          sfk lf-to-crlf - convert from LF to CRLF line endings
          sfk crlf-to-lf - convert from CRLF to LF line endings
          sfk detab      - convert TAB characters to spaces
          sfk entab      - convert groups of spaces to TAB chars
          sfk scantab    - list files containing TAB characters
          sfk split      - split large files into smaller ones
          sfk join       - join small files into a large one
          sfk hexdump    - create hexdump from a binary file
          sfk hextobin   - convert hex data to binary
          sfk hex        - convert decimal number(s) to hex
          sfk dec        - convert hex number(s) to decimal
          sfk chars      - print chars for a list of codes
          sfk bin-to-src - convert binary to source code
    
       text processing
          sfk filter     - search, filter and replace text data
          sfk addhead    - insert string at start of text lines
          sfk addtail    - append string at end of text lines
          sfk patch      - change text files through a script
          sfk snapto     - join many text files into one file
          sfk joinlines  - join text lines split by email reformatting
          sfk inst       - instrument c++ sourcecode with tracing calls
          sfk replace    - replace words in binary and text files
          sfk hexfind    - find words in binary files, showing hexdump
          sfk run        - run command on all files of a folder
          sfk runloop    - run a command n times in a loop
          sfk printloop  - print some text many times
          sfk strings    - extract strings from a binary file
          sfk sort       - sort text lines produced by another command
          sfk count      - count text lines, filter identical lines
          sfk head       - print first lines of a file
          sfk tail       - print last lines of a file
          sfk linelen    - tell length of string(s)
    
       search and compare
          sfk find       - find words in binary files, showing text
          sfk md5gento   - create list of md5 checksums over files
          sfk md5check   - verify list of md5 checksums over files
          sfk md5        - calc md5 over a file, compare two files
          sfk pathfind   - search PATH for location of a command
          sfk reflist    - list fuzzy references between files
          sfk deplist    - list fuzzy dependencies between files
          sfk dupfind    - find duplicate files by content
    
       networking
          sfk httpserv   - run an instant HTTP server.
                           type "sfk httpserv -help" for help.
          sfk ftpserv    - run an instant FTP server
                           type "sfk ftpserv -help" for help.
          sfk ftp        - instant anonymous FTP client
          sfk wget       - download HTTP file from the web
          sfk webrequest - send HTTP request to a server
          sfk tcpdump    - print TCP conversation between programs
          sfk udpdump    - print incoming UDP requests
          sfk udpsend    - send UDP requests
          sfk ip         - tell own machine's IP address(es).
                           type "sfk ip -help" for help.
          sfk netlog     - send text outputs to network,
                           and/or file, and/or terminal
    
       scripting
          sfk script     - run many sfk commands in a script file
          sfk echo       - print (coloured) text to terminal
          sfk color      - change text color of terminal
          sfk alias      - create command from other commands
          sfk mkcd       - create command to reenter directory
          sfk sleep      - delay execution for milliseconds
          sfk pause      - wait for user input
          sfk label      - define starting point for a script
          sfk tee        - split command output in two streams
          sfk tofile     - save command output to a file
          sfk toterm     - flush command output to terminal
          sfk loop       - repeat execution of a command chain
          sfk cd         - change directory within a script
          sfk getcwd     - print the current working directory
          sfk require    - compare version text
    
       development
          sfk bin-to-src - convert binary data to source code
          sfk make-random-file - create file with random data
          sfk fuzz       - change file at random, for testing
          sfk sample     - print example code for programming
          sfk inst       - instrument c++ with tracing calls
    
       diverse
          sfk media      - cut video and binary files
          sfk view       - show results in a GUI tool
          sfk toclip     - copy command output to clipboard
          sfk fromclip   - read text from clipboard
          sfk list       - show directory tree contents
          sfk env        - search environment variables
          sfk version    - show version of a binary file
          sfk ascii      - list ISO 8859-1 ASCII characters
          sfk ascii -dos - list OEM codepage 850 characters
          sfk license    - print the SFK license text
    
       help by subject
          sfk help select   - how dirs and files are selected in sfk
          sfk help options  - general options reference
          sfk help patterns - wildcards and text patterns within sfk
          sfk help chain    - how to combine (chain) multiple commands
          sfk help shell    - how to optimize the windows command prompt
          sfk help unicode  - about unicode file reading support
          sfk help colors   - how to change result colors
          sfk help xe       - for infos on sfk extended edition.
    
       All tree walking commands support file selection this way:
    
       1. short format with ONE directory tree and MANY file name patterns:
          src1dir .cpp .hpp .xml bigbar !footmp
       2. short format with a list of explicite file names:
          letter1.txt revenues9.xls report3\turnover5.ppt
       3. long format with MANY dir trees and file masks PER dir tree:
          -dir src1 src2 !src\save -file foosys .cpp -dir bin5 -file .exe
    
       For detailed help on file selection, type "sfk help select".
    
       * and ? wildcards are supported within filenames. "foo" is interpreted
       as "*foo*", so you can leave out * completely to search a part of a name.
       For name start comparison, say "\foo" (finds foo.txt but not anyfoo.txt).
    
       When you supply a directory name, by default this means "take all files".
    
          sfk list mydir                lists ALL  files of mydir, no * needed.
          sfk list mydir .cpp .hpp      lists SOME files of mydir, by extension.
          sfk list mydir !.cfg          lists all  files of mydir  EXCEPT .cfg
    
       general options:
          -tracesel tells in detail which files and/or directories are included
                    or excluded, and why (due to which user-supplied mask).
          -nosub    do not process files within subdirectories.
          -nocol    before any command switches off color output.
          -quiet    or -nohead shows less output on some commands.
          -hidden   includes hidden and system files and dirs.
          For detailed help on all options, type "sfk help options".
    
       beware of Shell Command Characters.
          command parameters containing characters < > | ! & must be sur-
          rounded by quotes "". type "sfk filter" for details and examples.
    
       type "sfk ask word1 word2 ..."   to search ALL help text for words.
       type "sfk dumphelp"              to print  ALL help text.
    

    编辑:请注意:在包含二进制文件的文件夹上运行此程序时要小心,因为它会有效地破坏您的文件,尤其是 .git 目录。如果是这种情况,请不要在整个文件夹中运行 sfk,而是选择特定的文件扩展名(*.rb、*.py 等)。示例:sfk remcr -dir chef -file .rb -file .json -file .erb -file .md

    【讨论】:

    • 在 OSX Mavericks 上效果很好。无需安装任何东西,只需从已安装的 dmg 运行脚本,您的终端就可以使用了。
    • @Gui Ambros 您无需担心 .git 文件夹中的文件。 sfk 默认不更新隐藏文件夹中的文件。
    • @bittusarkar:在我回答时,sfk 有效地处理了我的整个 .git 文件夹并销毁了一堆二进制文件(因此我的 edit;不记得了如果是 Linux 或 Mac)。他们可能在较新的版本中更改了默认行为,但为了安全起见,我仍然建议指定扩展名。
    • 这对我来说效果很好,因为我花了太多时间尝试使用推荐的 git 命令来规范我的存储库,但这些命令根本没有修复所有相关文件。
    • 谢谢!只是用它来快速、轻松地转换一大堆文件,现在我可以将它们添加到 Git 的暂存区域。在 OSX 10.9.5 上,不确定文件是在哪里创建的。
    猜你喜欢
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 2021-12-25
    • 2013-07-08
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多