用Perl中的连字符替换空格

时间:2012-10-11 22:35:34

标签: perl

我想用连字符替换所有空格,但空格将替换为045而不是-。表达式是:

s/ /-/g

表达式s/ /_/g(使用下划线)可以正常工作,所以我不确定为什么i have apples成为

i,045have,045apples

3 个答案:

答案 0 :(得分:5)

此代码适用于我:

#!/usr/bin/perl
use v5.14;
use strict;
use warnings;
my $test = "I like Apples";
$test=~s/ /-/g;
say $test;

输出I-like-Apples

如果您提供了更多信息,我们可以帮助您提供有关代码行为不当的更多信息。

我们想要的信息:

  • 您如何查看输出?
  • 使用什么字符集(shell中的$ LANG)
  • 你在哪个平台?
  • 什么版本的perl?
  • 您是否在代码中的任何位置弄乱了本地或字符集?
  • 请提供更多代码,即不仅仅是替换代码的行,如何获取字符串以及如何打印它?

答案 1 :(得分:2)

这段代码非常适合我:

echo I have apples | perl -p -e 's/\ /-/g'
I-have-apples

答案 2 :(得分:0)

我在某处找到了一个片段,并将其充血了。尚未完全完成,但目前已进行了足够的工作。

#!/usr/bin/perl
#=====================================================================
#
# Convert all directory and file names to change spaces (and other special characters) to underscores...
#
# Initial Author: Dean Weiten
#
# Create Date: 2018-08-25
# Design Name: fix_dir_and_file_names.pl
# Tool versions: Perl version >= v5.8.5
#
# Description:
#    
#
# Dependencies:
#
# Revision:
#
#   $Log: fix_dir_and_file_names.pl,v $
#
#
# Additional Comments:
#
# "Nothing focusses the mind so well as an execution in the morning"
#
# Reminder: to add a module from CPAN, do something like this (may have to be root):
#   perl -MCPAN -e 'install Math::FFT'
#
#=====================================================================


# System modules
use File::Rename;
use Text::ParseWords;
use IO::Handle;
use Getopt::Std;
use POSIX;
use Switch;
use List::Util;
use File::Temp qw/ tempfile tempdir /;


$VERSION        = 0;
$ISSUE          = 1;
$ISSUE_DATE     = "2018-08-25";

$Debug = 0;


    # MAIN

    # Logical values
    my  $TRUE           = 1;
    my  $FALSE          = 0;

    # Get present date and time by shelling out to the O/S.
    my $UTCDateAndTimeNow = `date --utc '+%Y-%m-%d %H:%M %::z %Z'`;
    # Get rid of trailing NewLine...
    $UTCDateAndTimeNow =~ s/\n//;
    $UTCDateAndTimeNow =~ s/\r//;

    # Get command line options, listed in alphabetic order...
    getopts('dhHtv');

        $Debug                  = $opt_d;
    my  $DoHelp                 = $opt_h || $opt_H;
    my  $NotVerbose             = $opt_v;
    my  $JustATest              = $opt_t;

    my  $Verbose;
    if  (!$NotVerbose)
        {
        $Verbose = $TRUE;
        }
    else
        {
        $Verbose = $FALSE;
        }

    my  $PassCount;

    print "\n\nRemove Special Characters from Directory Names";
    print   "\n----------------------------------------------";
    $Directories = $TRUE;   # For directories, we get rid of all dots in the directory name.

    $PassCount = 0;
    my  $NumberOfDirectoriesChanged = rena(`find \* -type d`);
    $PassCount++;
    print "\n\nPass ".$PassCount.", NumberOfDirectoriesChanged = ".$NumberOfDirectoriesChanged;
    my  $OldNumberOfDirectoriesChanged = 0;

    # Sometimes the find command puts subdirectories first, in which case the subdirectory name changes will fail
    # until the upper level is corrected.  Then we recurse.
    # BUT sometimes some files are just not changeable, for whatever reason... then we get 2 consecutive with the 
    # same number of files (attempted) to be changed, then we bail with a message.
    while (($NumberOfDirectoriesChanged > 0) && ($OldNumberOfDirectoriesChanged != $NumberOfDirectoriesChanged))
        {
        $OldNumberOfDirectoriesChanged = $NumberOfDirectoriesChanged;
        $NumberOfDirectoriesChanged = rena(`find \* -type d`);
        $PassCount++;
        print "\n\nPass ".$PassCount.", NumberOfDirectoriesChanged = ".$NumberOfDirectoriesChanged;
        }

    if  ($NumberOfDirectoriesChanged != 0)
        {
        print "\n\nNOTE: there are still ".$NumberOfDirectoriesChanged." directories to be changed, but they won't seem to change for us, skipping and continuing with files.";
        }


    print "\n\nRemove Special Characters from File Names";
    print   "\n-----------------------------------------";
    $Directories = $FALSE;  # For files, we will leave one dot in the file name, the last one encoutered.

    $PassCount = 0;
    my  $NumberOfFilesChanged = rena(`find \* -type f`);
    $PassCount++;
    print "\n\nPass ".$PassCount.", NumberOfFilesChanged = ".$NumberOfFilesChanged;
    my  $OldNumberOfFilesChanged = 0;

    while (($NumberOfFilesChanged > 0) && ($OldNumberOfFilesChanged != $NumberOfFilesChanged))
        {
        $OldNumberOfFilesChanged = $NumberOfFilesChanged;
        $NumberOfFilesChanged = rena(`find \* -type f`);
        $PassCount++;
        print "\n\nPass ".$PassCount.", NumberOfFilesChanged = ".$NumberOfFilesChanged;
        }

    if  ($NumberOfFilesChanged != 0)
        {
        print "\n\nNOTE: there are still ".$NumberOfFilesChanged." files to be changed, but they won't seem to change for us, skipping to completion.";
        }


    sub rena
        {
        my  $ChangeCount = 0;

        @InputList = @_;

        $ListCount = @InputList;

        if  ($Verbose)
            {
            print "\n\n--- ListCount = ", $ListCount;

            if  ($Directories)
                {
                print " directories";
                }
            else    
                {
                print " files.";
                }
            }

        for ($InputCounter = 0; $InputCounter < $ListCount; $InputCounter++)
            {
            $PresentLine = @InputList [ $InputCounter ];

            # Get rid of trailing NewLine...
            $PresentLine =~ s/\n//;
            $PresentLine =~ s/\r//;

            #$Line[ $InputCounter ] = $PresentLine;

            $_ = $PresentLine;

            # Trailing space
            s/ $//g;

            # non ascii transliterate
            tr [\200-\377][_];
            tr [\000-\40][_];

            # get rid of braces of all kinds
            #s/\{\}\[\]\(\)//g;

            # special characters we do not want in paths
            s/[ \,\;\?\+\'\"\!\[\]\(\)\@\#\{\}]/_/g;

            # underscore dash underscore
            s/_-_/-/g;

            if  ($Directories)
                {
                # get rid of all dots
                s/\./_/g
                }
            else
                {
                # files: only last dot left behind
                while (/\..*\./)
                    {
                    s/\./_/;
                    }
                }

            # only one _ consecutive
            s/_+/_/g;

            #next if ($_ eq $PresentLine ) or ("./$_" eq $PresentLine);

            if  ($_ eq $PresentLine)
                {
                #print "\n".$InputCounter." ".$PresentLine;
                #print " -> no change";
                }
            else
                {
                if  ($Verbose)
                    {
                    print "\n".$InputCounter." ".$PresentLine;
                    print " -> ".$_;
                    }

                if  ($JustATest)
                    {
                    if  ($Verbose)
                        {
                        print " --- just testing, so not performed";
                        }
                    }
                else
                    {
                    #if  ($Verbose)
                    #    {
                    #    print " --- would have been performed";
                    #    }
                    rename ($PresentLine,$_);
                    $ChangeCount++;
                    }
                }

            }

        #print "\n\nChangeCount = ".$ChangeCount;
        return $ChangeCount;
        }

    print "\n\nCompleted.";
    print   "\n----------\n\n";