如何阅读/修改/删除applescript中列表中包含的项目/列表

时间:2013-02-19 17:22:04

标签: macos csv applescript

这个问题来自我之前的问题How to transform a CSV into several lists (applescript)?

我有一个大约4000行的csv文件。我导入它并将每一行作为一个列表的项目,然后我将每行作为它自己的项目列表。

例如:(我使用数字,但我的数据也包含文本,大多数条目都超过1个字符,有些条目也是空白的)

1,2,3,4,5,6
6,5,4,3,2,1
7,8,9,0,7,6
3,4,4,5,3,1

变为

{"1,2,3,4,5,6","6,5,4,3,2,1","7,8,9,0,7,6","3,4,4,5,3,1"}

变为

{{"1","2","3","4","5","6"}{"6","5","4","3","2","1"}{"7","8","9","0","7","6"}{"3","4","4","5","3","1"}}

现在我希望能够做到的是:

从每个列表中删除某些项目,例如我想删除每个列表中的第二个项目,即“2”,“5”,“8”和“4”

对某些项目运行计算,例如我想将项目5乘以2

我的数据中的一些数字在它们的末尾有+11或+17,我想知道如何用匹配的零值替换它,例如,如果我有5002 + 6我我想把它变成5002000000

目前的代码是:

-- Choosing your file
set csvDevices to "testfile.csv"

-- Reading file to memory
set csvDevices to read csvDevices

-- Creating Records (Single Lines)
set csvDevicesRecords to paragraphs of csvDevices

-- Remove Title Line
set csvDevicesRecords to rest of csvDevicesRecords

-- Make each line into a list
set csvDevicesValues to {}
set AppleScript's text item delimiters to ","
repeat with i from 1 to length of csvDevicesRecords
    set end of csvDevicesValues to text items of (item i of csvDevicesRecords)
end repeat
set AppleScript's text item delimiters to ""

我希望以上都是有道理的。

3 个答案:

答案 0 :(得分:0)

如果你自己写一个子程序来为你做这些事情,那真的不难。这是您要求的3。您需要添加其他子例程,以便进行其他数学运算(加,减和除)。只需复制multiplyItemNumberByValue()子例程并将操作符更改为适当的子例程,它应该无需进一步更改即可使用。

祝你好运。

set listOfLists to {{"1", "2+2", "3", "4", "5", "6"}, {"6", "5", "4", "3", "2", "1"}, {"7", "8", "9", "0", "7", "6"}, {"3", "4", "4", "5+3", "3", "1"}}

-- before performing any other operation, expand all zeros
set listOfLists to expandZeros(listOfLists)

-- remove item 2 from every sublist
set listOfLists to removeItemNumber(listOfLists, 2)

-- multiply item 1 of every sublist by 5
set listOfLists to multiplyItemNumberByValue(listOfLists, 1, 5)




(****************** SUBROUTINES ******************)
on multiplyItemNumberByValue(listOfLists, itemNumber, theValue)
    set newList to {}
    repeat with i from 1 to count of listOfLists
        set thisList to item i of listOfLists
        set thisItem to item itemNumber of thisList
        set newValue to (thisItem as number) * theValue
        set item itemNumber of thisList to (newValue as text)
        set end of newList to thisList
    end repeat
    return newList
end multiplyItemNumberByValue

on removeItemNumber(listOfLists, itemNumber)
    set newList to {}
    repeat with i from 1 to count of listOfLists
        set thisList to item i of listOfLists
        if itemNumber is equal to 1 then
            set newSublist to items 2 thru end of thisList
        else if itemNumber is equal to (count of thisList) then
            set newSublist to items 1 thru (itemNumber - 1) of thisList
        else
            set newSublist to items 1 thru (itemNumber - 1) of thisList & items (itemNumber + 1) thru end of thisList
        end if
        set end of newList to newSublist
    end repeat
    return newList
end removeItemNumber

on expandZeros(listOfLists)
    set newList to {}
    repeat with i from 1 to count of listOfLists
        set thisList to item i of listOfLists
        set newSublist to {}
        repeat with j from 1 to count of thisList
            set subItem to item j of thisList
            if subItem contains "+" then
                set x to offset of "+" in subItem
                if x is equal to 0 or x is equal to 1 or x is equal to (count of subItem) then
                    set end of newSublist to subItem -- do nothing
                else
                    set a to text 1 thru (x - 1) of subItem
                    set b to text (x + 1) thru end of subItem
                    repeat (b as number) times
                        set a to a & "0"
                    end repeat
                    set end of newSublist to a
                end if
            else
                set end of newSublist to subItem -- do nothing
            end if
        end repeat
        set end of newList to newSublist
    end repeat
    return newList
end expandZeros

这是其他数学子程序......

on divideItemNumberByValue(listOfLists, itemNumber, theValue)
    set newList to {}
    repeat with i from 1 to count of listOfLists
        set thisList to item i of listOfLists
        set thisItem to item itemNumber of thisList
        set newValue to (thisItem as number) / theValue
        set item itemNumber of thisList to (newValue as text)
        set end of newList to thisList
    end repeat
    return newList
end divideItemNumberByValue

on addValueToItemNumber(listOfLists, itemNumber, theValue)
    set newList to {}
    repeat with i from 1 to count of listOfLists
        set thisList to item i of listOfLists
        set thisItem to item itemNumber of thisList
        set newValue to (thisItem as number) + theValue
        set item itemNumber of thisList to (newValue as text)
        set end of newList to thisList
    end repeat
    return newList
end addValueToItemNumber

on subtractValueFromItemNumber(listOfLists, itemNumber, theValue)
    set newList to {}
    repeat with i from 1 to count of listOfLists
        set thisList to item i of listOfLists
        set thisItem to item itemNumber of thisList
        set newValue to (thisItem as number) - theValue
        set item itemNumber of thisList to (newValue as text)
        set end of newList to thisList
    end repeat
    return newList
end subtractValueFromItemNumber

答案 1 :(得分:0)

Nigel Garvey's CSV-to-list converter是我见过的最好的。

您可以这样称呼它:

    set filePath to "/Users/You/Desktop/myCsv.csv"
    set csvData to do shell script "cat " & quoted form of filePath
    set csvDevicesLists to csvToList(csvData, {trimming:true})

--> {{"1", "2", "3", "4", "5", "6"}, {"6", "5", "4", "3", "2", "1"}, {"7", "8", "9", "0", "7", "6"}, {"3", "4", "4", "5", "3", "1"}}

你可以像这样填充零:

set xxx to {{"1", "2", "3+2", "4", "52+3", "6"}, {"6", "5", "4+5", "3", "2", "1"}}
repeat with i from 1 to count of xxx
    if (item i of xxx as text) contains "+" then
        set temp to {}
        repeat with anItem in item i of xxx
            set end of temp to (do shell script "echo " & quoted form of anItem & " | sed s/+/*10^/ | bc")
        end repeat
        set item i of xxx to temp
    end if
end repeat
return xxx

ASObjC Runner也为操作列表提供了一些很好的工具。

答案 2 :(得分:-2)

使用Ruby或Python(或几乎任何其他语言)会更容易:

"1,2,3+11,4,5,6
6,5,4,3,2,1+17".split("\n").each { |n|
  n.gsub!(/\+(\d+)/, "0" * $1.to_i)
  c = n.split(",")
  c[4] = c[4].to_i * 5
  c.delete_at(1)
  puts c.join(",")
}