4

バッチファイルを使用して文字列を挿入し、特定の列の空のスペースを置き換えたいのですが、次のようなinput.txtがあるとします

field1      field2           field3
AAAAA       BBBBB            CCCCC
DDDDD                        EEEEE
FFFFF                        
GGGGG       HHHHH 

空の各フィールドに文字列「NULL」を挿入する必要があり、フィールド 1 が空ではなく、フィールド 2,3がいつか空になることを確認します。さらに、field1 と field2 の間のスペースは、field2 と field3 とは異なります

output.txt

field1      field2           field3
AAAAA       BBBBB            CCCCC
DDDDD       NULL             EEEEE
FFFFF       NULL             NULL    
GGGGG       HHHHH            NULL

まだバッチ ファイル スクリプトを実行する必要があるため、コードを記述しようとしました (フィールド 2 は常に左から 12 文字、フィールド 3 は常に左から 29 文字です)。

@echo off

set line= 
for /F in (input.txt)do
if "!line:~12" equ " " 
write "NULL"   >> (i am not sure whether this work)

if "!line:~29" equ " "
write "NULL"  

echo .>> output.txt

おそらく、誰かが私の間違いを修正できますか?ありがとう!!

4

2 に答える 2

1

約束どおり、Python での解決策を次に示します。このプログラムは、Python 3.x または Python 2.7 で問題なく動作します。プログラミングが初めての場合は、Python 3.x をお勧めします。Python 3.x の方が習得しやすいと思います。ここから無料で Python を入手できます: http://python.org/download/

Python の最新バージョンはバージョン 3.2.3 です。それを取得することをお勧めします。

という名前のファイルに Python コードを保存add_null.pyし、次のコマンドで実行します。

python add_null.py input_file.txt output_file.txt

多くのコメントを含むコード:

# import brings in "modules" which contain extra code we can use.
# The "sys" module has useful system stuff, including the way we can get
# command-line arguments.
import sys

# sys.argv is an array of command-line arguments.  We expect 3 arguments:
# the name of this program (which we don't care about), the input file
# name, and the output file name.
if len(sys.argv) != 3:
    # If we didn't get the right number of arguments, print a message and exit.
    print("Usage: python add_null.py <input_file> <output_file>")
    sys.exit(1)

# Unpack the arguments into variables.  Use '_' for any argument we don't
# care about.
_, input_file, output_file = sys.argv


# Define a function we will use later.  It takes two arguments, a string
# and a width.
def s_padded(s, width):
    if len(s) >= width:
        # if it is already wide enough, return it unchanged
        return s
    # Not wide enough!  Figure out how many spaces we need to pad it.
    len_padding = width - len(s)
    # Return string with spaces appended.  Use the Python "string repetition"
    # feature to repeat a single space, len_padding times.
    return s + ' ' * len_padding


# These are the column numbers we will use for splitting, plus a width.
# Numbers put together like this, in parentheses and separated by commas,
# are called "tuples" in Python.  These tuples are: (low, high, width)
# The low and high numbers will be used for ranges, where we do use the
# low number but we stop just before the high number.  So the first pair
# will get column 0 through column 11, but will not actually get column 12.
# We use 999 to mean "the end of the line"; if the line is too short, it will
# not be an error.  In Python "slicing", if the full slice can't be done, you
# just get however much can be done.
#
# If you want to cut off the end of lines that are too long, change 999 to
# the maximum length you want the line ever to have.  Longer than
# that will be chopped short by the "slicing".
#
# So, this tells the program where the start and end of each column is, and
# the expected width of the column.  For the last column, the width is 0,
# so if the last column is a bit short no padding will be added.  If you want
# to make sure that the lines are all exactly the same length, change the
# 0 to the width you want for the last column.
columns = [ (0, 12, 12), (12, 29, 17), (29, 999, 0) ]
num_columns = len(columns)

# Open input and output files in text mode.
# Use a "with" statement, which will close the files when we are done.
with open(input_file, "rt") as in_f, open(output_file, "wt") as out_f:
    # read the first line that has the field headings
    line = in_f.readline()
    # write that line to the output, unchanged
    out_f.write(line)

    # now handle each input line from input file, one at a time
    for line in in_f:
        # strip off only the line ending
        line = line.rstrip('\n')

        # start with an empty output line string, and append to it
        output_line = ''
        # handle each column in turn
        for i in range(num_columns):
            # unpack the tuple into convenient variables
            low, high, width = columns[i]
            # use "slicing" to get the columns we want
            field = line[low:high]
            # Strip removes spaces and tabs; check to see if anything is left.
            if not field.strip():
                # Nothing was left after spaces removed, so put "NULL".
                field = "NULL"

            # Append field to output_line.  field is either the original
            # field, unchanged, or else it is a "NULL".  Either way,
            # append it.  Make sure it is the right width.
            output_line += s_padded(field, width)

        # Add a line ending to the output line.
        output_line += "\n"
        # Write the output line to the output file.
        out_f.write(output_line)

このプログラムの実行による出力:

field1      field2           field3
AAAAA       BBBBB            CCCCC
DDDDD       NULL             EEEEE
FFFFF       NULL             NULL
GGGGG       HHHHH            NULL
于 2012-06-15T03:45:25.680 に答える
0

あなたがやりたいことは、Microsoft の「バッチ」スクリプトでは実現できないと思いました。ただし、ここに文書化された文字列演算子の完全なセットがあります。

http://www.dostips.com/DtTipsStringManipulation.php

しかし、バッチファイルはひどいので、もっと良いものを使用していただければ幸いです。Python ソリューションまたは AWK が必要な場合は、お手伝いします。

私があなたの立場で、実際にこれを「バッチ」スクリプトで行うとしたら、~x,y列スライシングを使用して、各行を 3 つの部分文字列に分割します (ここxで、 は最初の列で、yは 2 番目の列です)。次に、それぞれが単なるスペースかどうかを確認し、スペースだけのものについては「NULL」に置き換えます。次に、部分文字列を 1 つの文字列に再結合し、それを出力します。これをループ内で実行すると、プログラムが完成します。

于 2012-06-15T02:19:00.683 に答える